﻿using AutoMapper;
using AutoMapper.Internal.Mappers;
using Microsoft.Extensions.DependencyInjection;
using Niaofei.Application.Contracts;
using Niaofei.Domain;
using Niaofei.Injcetion;

namespace Niaofei.Application
{
    [Injection(typeof(ISysDictAppService))]
    internal class SysDictAppService : NiaofeiAppService, ISysDictAppService
    {
        private readonly ISysDictRepository _sysDictRepository;
        private readonly ISysDictTypeRepository _sysDictTypeRepository;

        public SysDictAppService(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _sysDictRepository = serviceProvider.GetRequiredService<ISysDictRepository>();
            _sysDictTypeRepository = serviceProvider.GetRequiredService<ISysDictTypeRepository>();
        }

        public async Task<ResultDto<SysDictTypeDto>> AddDictType(SysDictTypeDto input)
        {
            var entity = Mapper.Map<SysDictTypeDto, SysDictType>(input);

            entity.UserId = CurrentUser?.Id.ToString() ?? "";
            entity = await _sysDictTypeRepository.InsertAsync(entity);

            input = Mapper.Map<SysDictType, SysDictTypeDto>(entity);

            return new ResultDto<SysDictTypeDto>(input);
        }

        public async Task<ResultDto<SysDictTypeDto>> GetDictType(SysDictTypeInputDto input)
        {
            var query = await _sysDictTypeRepository.GetQueryableAsync();

            var entity = query.WhereIf(input.Id != null, m => m.Id == input.Id)
                .WhereIf(!string.IsNullOrEmpty(input.Code), m => m.Code == input.Code)
                .WhereIf(!string.IsNullOrEmpty(input.Name), m => m.Code == input.Name)
                .FirstOrDefault();

            if (entity == null)
            {
                return new ResultDto<SysDictTypeDto>("类型未找到");
            }

            var result = Mapper.Map<SysDictType, SysDictTypeDto>(entity);

            return new ResultDto<SysDictTypeDto>(result);
        }

        public async Task<ResultDto<PageOutputDto<SysDictTypeDto>>> GetDictTypePage(SysDictTypePageInputDto input)
        {
            var query = await _sysDictTypeRepository.GetQueryableAsync();

            query = query.WhereIf(input.Id != null, m => m.Id == input.Id)
                .WhereIf(!string.IsNullOrEmpty(input.Code), m => m.Code == input.Code)
                .WhereIf(!string.IsNullOrEmpty(input.Name), m => m.Name.Contains(input.Name));

            var count = query.Count();

            var list = query.Skip((input.PageNo - 1) * input.PageSize).Take(input.PageSize).ToList();

            var result = Mapper.Map<List<SysDictType>, List<SysDictTypeDto>>(list);

            return new ResultDto<PageOutputDto<SysDictTypeDto>>()
            {
                Code = "0",
                Data = new PageOutputDto<SysDictTypeDto>(count, result),
            };
        }

        public async Task<ResultDto> RemoveDictType(List<int> ids)
        {
            var query = await _sysDictTypeRepository.GetQueryableAsync();

            var list = query.Where(m => ids.Contains(m.Id)).ToList();

            if (list.Count == 0)
            {
                return new ResultDto() { Code = "1", Message = "未找到相关的数据" };
            }

            await _sysDictTypeRepository.DeleteManyAsync(list);

            return new ResultDto() { Code = "0", Data = "成功" };
        }

        public async Task<ResultDto<SysDictTypeDto>> UpdateDictType(SysDictTypeDto input)
        {
            var query = await _sysDictTypeRepository.GetQueryableAsync();

            var entity = query.FirstOrDefault(m => m.Id == input.Id);

            if (entity == null)
            {
                return new ResultDto<SysDictTypeDto>("数据未找到");
            }

            Mapper.Map(input, entity);

            entity = await _sysDictTypeRepository.UpdateAsync(entity);

            input = Mapper.Map<SysDictType, SysDictTypeDto>(entity);

            return new ResultDto<SysDictTypeDto>(input);
        }

        public async Task<ResultDto<PageOutputDto<SysDictDto>>> GetDictPage(SysDictInputDto input)
        {
            var query = await _sysDictRepository.GetQueryableAsync();

            query = query.Where(m => m.SysDictTypeId == input.SysDictTypeId)
                .WhereIf(input.IsDefault.HasValue, m => m.IsDefault == input.IsDefault)
                .WhereIf(input.Status.HasValue, m => m.Status == input.Status)
                .WhereIf(!string.IsNullOrEmpty(input.KeyWord), m => m.Name.Contains(input.KeyWord) ||
                    m.TypeCode.Contains(input.KeyWord) || m.Remark.Contains(input.KeyWord))
                .OrderBy(m => m.Sort);

            var count = query.Count();

            var list = query.Skip((input.PageNo - 1) * input.PageSize).Take(input.PageSize).ToList();

            var result = Mapper.Map<List<SysDict>, List<SysDictDto>>(list);

            return new ResultDto<PageOutputDto<SysDictDto>>()
            {
                Code = "0",
                Data = new PageOutputDto<SysDictDto>(count, result),
            };
        }

        public async Task<ResultDto<SysDictDto>> AddDict(SysDictDto input)
        {
            var entity = Mapper.Map<SysDictDto, SysDict>(input);

            entity = await _sysDictRepository.InsertAsync(entity);

            var result = Mapper.Map<SysDict, SysDictDto>(entity);

            return new ResultDto<SysDictDto>(result);
        }

        public async Task<ResultDto<SysDictDto>> UpdateDict(SysDictDto input)
        {
            var entity = (await _sysDictRepository.GetQueryableAsync())
                .FirstOrDefault(m => m.Id == input.Id);

            if (entity == null)
            {
                return new ResultDto<SysDictDto>("Id对应数据不存在");
            }

            Mapper.Map(input, entity);

            await _sysDictRepository.UpdateAsync(entity);

            var result = Mapper.Map<SysDict, SysDictDto>(entity);

            return new ResultDto<SysDictDto>(result);
        }

        public async Task<ResultDto> RemoveDict(List<int> ids)
        {
            var entitys = (await _sysDictRepository.GetQueryableAsync())
                .Where(m => ids.Contains(m.Id))
                .ToList();

            if (entitys.Count == 0)
            {
                return new ResultDto() { Code = "1"};
            }

            await _sysDictRepository.DeleteManyAsync(entitys);

            return new ResultDto() { Code = "0" };
        }
    }
}
